import json
import re

from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django.contrib.auth import login
from django.http import HttpResponseForbidden
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views import View
from django_redis import get_redis_connection

from carts.utils import merge_cart
from oatuh.models import OAuthQQUser, OAuthSinaUser
from oatuh.utils import encrypt, decipher
from users.models import User

from meiduo_mall.apps.oatuh import sinaweibopy3
from meiduo_mall.utils.response_code import RET

'''
>>> from django.conf import settings
>>> from QQLoginTool.QQtool import OAuthQQ
>>> oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)
>>> login_url = oauth.get_qq_url()
>>> print(login_url)
https://graph.qq.com/oauth2.0/authorize?response_type=code&redirect_uri=http%3A%2F%2Fwww.meiduo.site%3A8000%2Foauth_callback&client_id=101518219&state=%3Cbuilt-in+function+next%3E
>>> access_token = oauth.get_access_token("76DD2867324E60D74571A153392F35C5")
>>> print(access_token)
FAA68857B3EAD36618CB730EE0AE0BB4
>>> openid = oauth.get_open_id("FAA68857B3EAD36618CB730EE0AE0BB4")
>>> print(openid)
7A070D3184FEA097EDE18A4F6ABF892B
>>>



'''


class OAuthQQLoginView(View):

    def get(self, request):

        # 1. 获取参数
        state = request.GET.get("next", "/")

        # 创建OAuthQQ对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                             redirect_uri=settings.QQ_REDIRECT_URI, state=next)

        login_url = oauth.get_qq_url()

        data = {"login_url":login_url}

        return JsonResponse(data)


class OAuthUserView(View):
    def get(self, request):
        code = request.GET.get("code")
        state = request.GET.get("state")
        # print(code)

        if not code:
            return HttpResponseForbidden("code丢失了....")

        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        access_token = oauth.get_access_token(code)

        # 通过access_token换取openid
        openid = oauth.get_open_id(access_token)

        # 根据openid提取到qq用户对象
        try:
            # 再oauth_qq_user表中查询并且返回一个模型类
            oauth_qq_user = OAuthQQUser.objects.get(openid=openid)

        # 初次授权
        except OAuthQQUser.DoesNotExist:

            s_openid = encrypt(openid)

            context = {"token":s_openid}

            return render(request, "oauth_callback.html", context)

        else:
            # 非初次授权
            # 状态保持
            # 通过 模型类.foreign_key 获取tb_users表中对应的模型类
            meiduo_user = oauth_qq_user.user
            login(request, meiduo_user)
            request.session.set_expiry(2*24*3600)

            # 设置首页中显示用户名称的cookie，并且返回响应
            response = redirect("/")
            response.set_cookie("username", meiduo_user.username)

            merge_cart(request, request.user, response)

            return response

    def post(self, request):

        # 获取提交表单里面的数据
        mobile = request.POST.get("mobile")
        pwd = request.POST.get("pwd")
        sms_code = request.POST.get("sms_code")
        s_openid = request.POST.get("access_token")

        # 为空判断
        if not all([mobile, pwd, sms_code, s_openid]):
            return HttpResponseForbidden("参数不全...")

        # 手机号的格式判断
        if not re.match("1[3-9]\d{9}", mobile):
            return HttpResponseForbidden("手机格式不正确...")

        # 密码的格式判断
        if not re.match("^[0-9A-Za-z]{8,20}$", pwd):
            return HttpResponseForbidden("密码格式不正确...")

        # 短信验证码的校验
        conn = get_redis_connection("code")
        redis_msg_code = conn.get("sms_code_%s" % mobile)

        if not redis_msg_code:
            return HttpResponseForbidden("手机验证码已经过期了...")

        if not redis_msg_code.decode() == sms_code:
            return HttpResponseForbidden("手机验证码输入错误...")

        # openid的解码
        openid = decipher(s_openid)

        # 判断是否存在美多用户
        try:
            user = User.objects.get(mobile=mobile)

        except User.DoesNotExist:
            # 创建美多用户
            user = User.objects.create_user(username=mobile, mobile=mobile, password=pwd)
            # 绑定美多用户和qq用户
            OAuthQQUser.objects.create(user=user, openid=openid)

            # 设置session
            login(request, user)
            request.session.set_expiry(2*24*3600)

            # 返回首页并且设置cookie
            response = redirect("/")
            response.set_cookie("username", user.username, max_age=2*24*3600)

            merge_cart(request, request.user, response)

            return response

        else:
            if not user.check_password(pwd):
                return HttpResponseForbidden("已经有美多用户，但是用户密码错误...")

            # 关联美多用户
            OAuthQQUser.objects.create(user=user, openid=openid)

            login(request, user)
            request.session.set_expiry(2*24*3600)

            response = redirect("/")
            response.set_cookie("username", user.username, max_age=2*24*3600)

            merge_cart(request, request.user, response)

            return response







class OAuthSinaLoginView(View):
    def get(self, request):

        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)

        login_url = client.get_authorize_url()

        data = {"login_url": login_url}

        return JsonResponse(data)


class OAuthSinaUserView(View):
    def get(self, request):
        return render(request, "sina_callback.html")

        # code = request.GET.get("code")
        #
        # client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
        #                                 redirect_uri=settings.REDIRECT_URL)
        #
        # result = client.request_access_token(code)
        # access_token = result.access_token
        # uid = result.uid
        #
        # # 根据openid提取到qq用户对象
        # try:
        #     # 再oauth_qq_user表中查询并且返回一个模型类
        #     oauth_sina_user = OAuthSinaUser.objects.get(uid=uid)
        #
        # # 初次授权
        # except OAuthSinaUser.DoesNotExist:
        #
        #     context = {"uid":uid}
        #
        #     return render(request, "sina_callback.html", context)
        #
        # else:
        #     # 非初次授权
        #     # 状态保持
        #     # 通过 模型类.foreign_key 获取tb_users表中对应的模型类
        #     meiduo_user = oauth_sina_user.user
        #     login(request, meiduo_user)
        #     request.session.set_expiry(2*24*3600)
        #
        #     # 设置首页中显示用户名称的cookie，并且返回响应
        #     response = redirect("/")
        #     response.set_cookie("username", meiduo_user.username)
        #
        #     merge_cart(request, request.user, response)
        #
        #     return response


class OAuthSinaCodeView(View):
    def get(self, request):
        code = request.GET.get("code")

        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)

        result = client.request_access_token(code)
        access_token = result.access_token
        uid = result.uid

        # 加密uid
        s_uid = encrypt(uid)
        # print(s_uid)
        # print(uid)

        # 根据openid提取到qq用户对象
        try:
            # 再oauth_qq_user表中查询并且返回一个模型类
            oauth_sina_user = OAuthSinaUser.objects.get(uid=uid)

        # 初次授权
        except:

            context = {"access_token": s_uid}

            return JsonResponse(context)

        else:
            # 非初次授权
            # 状态保持
            # 通过 模型类.foreign_key 获取tb_users表中对应的模型类
            meiduo_user = oauth_sina_user.user

            login(request, meiduo_user)
            request.session.set_expiry(2*24*3600)

            context = {"user_id": meiduo_user.id,
                       "user_name": meiduo_user.username,
                       "token": s_uid}

            # 设置首页中显示用户名称的cookie，并且返回响应
            response = JsonResponse(context)
            response.set_cookie("username", meiduo_user.username)
            merge_cart(request, request.user, response)

            return response

    def post(self, request):

        json_data = json.loads(request.body.decode())


        # 获取提交表单里面的数据
        mobile = json_data.get("mobile")
        pwd = json_data.get("password")
        sms_code = json_data.get("sms_code")
        s_uid = json_data.get("access_token")

        # 为空判断
        if not all([mobile, pwd, sms_code, s_uid]):
            return HttpResponseForbidden("参数不全...")

        # 手机号的格式判断
        if not re.match("1[3-9]\d{9}", mobile):
            return HttpResponseForbidden("手机格式不正确...")

        # 密码的格式判断
        if not re.match("^[0-9A-Za-z]{8,20}$", pwd):
            return HttpResponseForbidden("密码格式不正确...")

        # 短信验证码的校验
        conn = get_redis_connection("code")
        redis_msg_code = conn.get("sms_code_%s" % mobile)

        if not redis_msg_code:
            return HttpResponseForbidden("手机验证码已经过期了...")

        if not redis_msg_code.decode() == sms_code:
            return HttpResponseForbidden("手机验证码输入错误...")

        # uid的解码
        uid = decipher(s_uid)

        # 判断是否存在美多用户
        try:
            user = User.objects.get(mobile=mobile)

        except User.DoesNotExist:
            # 创建美多用户
            user = User.objects.create_user(username=mobile, mobile=mobile, password=pwd)
            # 绑定美多用户和qq用户
            OAuthSinaUser.objects.create(user=user, uid=uid)

            # 设置session
            login(request, user)
            request.session.set_expiry(2 * 24 * 3600)

            # 返回首页并且设置cookie
            response = JsonResponse({"status": RET.OK})
            response.set_cookie("username", user.username, max_age=2 * 24 * 3600)

            merge_cart(request, request.user, response)

            return response

        else:
            if not user.check_password(pwd):
                return HttpResponseForbidden("已经有美多用户，但是用户密码错误...")

            # 关联美多用户
            OAuthSinaUser.objects.create(user=user, uid=uid)

            login(request, user)
            request.session.set_expiry(2 * 24 * 3600)

            response = JsonResponse({"status": RET.OK})
            response.set_cookie("username", user.username, max_age=2 * 24 * 3600)

            merge_cart(request, request.user, response)

        return response






